#import "FifteenPuzzleModel.h"
#import "Tile.h"

@implementation FifteenPuzzleModel
@synthesize tileCollection;

-(id) init {
    [super init];
    tileCollection = [[NSMutableArray alloc] initWithCapacity:15];
    for (int i=0; i<15; i++) {
        CGRect tileFrame = CGRectMake(kLeftPadding + i%4 * 70.0, kTopPadding + i/4 * 70.0, 70, 70);
        Tile * tile = [[Tile alloc] init];
        tile.rect = tileFrame;
        tile.position = [[Position alloc] initWithCol:i%4 andRow:i/4];
        tile.n = i;
        [tileCollection addObject:tile];        
    }
    freeNeighbours = [[NSMutableArray alloc] initWithObjects:
                  [[Position alloc] initWithCol:2 andRow:3],
                  [[Position alloc] initWithCol:3 andRow:2],
                  [[Position alloc] initWithCol:4 andRow:3],
                  [[Position alloc] initWithCol:3 andRow:4],
                  nil
                  ];
    freePosition = [[Position alloc] initWithCol:3 andRow:3];
    return self;
}

-(void) changeAutoPosition: (int)p direction: (int)d {
    Tile * tile = [tileCollection objectAtIndex:p];
    Position * current = tile.position;
    tile.position = freePosition;
    freePosition = current;
    [self changeNeighboursPositions:d];
    [AppDelegate moveTileOn: tile.n withDirection: d];
}

- (void) changeNeighboursPositions: (int)direction {
    int dCol = 0; 
    int dRow = 0;
    switch (direction) {
        case 0:
            dCol = -1;
            break;
        case 1:
            dRow = -1;     
            break;
        case 2:
            dCol = 1;
            break;
        case 3:
            dRow = 1;
            break;
        default:
            break;
    }
    for (Position * p in freeNeighbours) {
        [p addCol:dCol andRow:dRow];
    }
}
-(void) moveTileWithIndex: (int)index {
    Tile * currentTile = [tileCollection objectAtIndex:index];
    int direction = -1;
    for(int i = 0; i<4; i++) {
        Position * p = [freeNeighbours objectAtIndex:i];
        if(currentTile.position.col == p.col 
           && currentTile.position.row == p.row) {
            direction = i;
            break;
        }
    }
    if (direction >= 0) {
        Position * temp = currentTile.position;
        currentTile.position = freePosition;
        freePosition = temp;
        [self changeNeighboursPositions:direction];
        [AppDelegate moveTileOn: currentTile.n withDirection: direction];
    }    
}

-(void) update: (int)t rect: (CGRect)newRect {
    Tile * tile = [tileCollection objectAtIndex:t];
    tile.rect = newRect;
}

- (void)dealloc {
    [tileCollection release];
    [freePosition release];
    [freeNeighbours release];
    [super dealloc];
}
@end
